package rexsee.barcode;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

import com.google.zxing.Result;

public class CaptureHandler extends Handler {

	private final BarcodeCaptureDialog mDialog;
	private final DecodeThread decodeThread;
	private State state;
	private enum State {
		PREVIEW, SUCCESS, DONE
	}

	public CaptureHandler(BarcodeCaptureDialog dialog) {
		mDialog = dialog;
		decodeThread = new DecodeThread(mDialog);
		try {
			decodeThread.start();
			state = State.SUCCESS;
			if (dialog.mCamera != null && !dialog.mPreviewing) {
				dialog.mCamera.startPreview();
				dialog.mPreviewing = true;
			}
			restartPreviewAndDecode();
		} catch (Exception e) {
			Toast.makeText(dialog.getContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
		}
	}
	@Override
	public void handleMessage(Message message) {
		try {
			switch (message.what) {
				case DecodeHandler.MESSAGE_AUTO_FOCUS :
					if (state == State.PREVIEW) {
						mDialog.mAutoFocusCallback.setHandler(this, DecodeHandler.MESSAGE_AUTO_FOCUS);
						mDialog.mCamera.autoFocus(mDialog.mAutoFocusCallback);
					}
					break;
				case DecodeHandler.MESSAGE_RESTART_PREVIEW :
					restartPreviewAndDecode();
					break;
				case DecodeHandler.MESSAGE_DECODE_SUCCEEDED :
					state = State.SUCCESS;
					Bundle bundle = message.getData();
					Bitmap barcode = bundle == null ? null : (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);
					mDialog.decode((Result) message.obj, barcode);
					break;
				case DecodeHandler.MESSAGE_DECODE_FAILED :
					state = State.PREVIEW;
					mDialog.mPreviewCallback.setHandler(decodeThread.getHandler(), DecodeHandler.MESSAGE_DECODE);
					if (mDialog.mUseOneShotPreviewCallback) {
						mDialog.mCamera.setOneShotPreviewCallback(mDialog.mPreviewCallback);
					} else {
						mDialog.mCamera.setPreviewCallback(mDialog.mPreviewCallback);
					}
					break;
			}
		} catch (Exception e) {
			Toast.makeText(mDialog.getContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
		}
	}
	public void quitSynchronously() {
		state = State.DONE;
		if (mDialog.mCamera != null && mDialog.mPreviewing) {
			if (!mDialog.mUseOneShotPreviewCallback) {
				mDialog.mCamera.setPreviewCallback(null);
			}
			mDialog.mCamera.stopPreview();
			mDialog.mPreviewCallback.setHandler(null, 0);
			mDialog.mAutoFocusCallback.setHandler(null, 0);
			mDialog.mPreviewing = false;
		}
		Message quit = Message.obtain(decodeThread.getHandler(), DecodeHandler.MESSAGE_QUIT);
		quit.sendToTarget();
		try {
			decodeThread.join();
		} catch (Exception e) {
		}
		// Be absolutely sure we don't send any queued up messages
		removeMessages(2);
		removeMessages(3);
	}
	private void restartPreviewAndDecode() {
		try {
			if (state == State.SUCCESS) {
				state = State.PREVIEW;
				mDialog.mPreviewCallback.setHandler(decodeThread.getHandler(), DecodeHandler.MESSAGE_DECODE);
				if (mDialog.mUseOneShotPreviewCallback) {
					mDialog.mCamera.setOneShotPreviewCallback(mDialog.mPreviewCallback);
				} else {
					mDialog.mCamera.setPreviewCallback(mDialog.mPreviewCallback);
				}
				mDialog.mAutoFocusCallback.setHandler(this, DecodeHandler.MESSAGE_AUTO_FOCUS);
				mDialog.mCamera.autoFocus(mDialog.mAutoFocusCallback);
				mDialog.mViewfinderView.drawViewfinder();
			}
		} catch (Exception e) {
			Toast.makeText(mDialog.getContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
		}
	}
}
